
/**
 * AppleIIGo
 * Speaker class
 * (C) 2008 by Marc S. Ressl (mressl@umich.edu)
 * Released under the GPL
 * Based on Blargg's http://www.slack.net/~ant/bl-synth
 */

#include "Motherboard.h"

#ifndef SPEAKER_H
#define SPEAKER_H

typedef enum {
	SPEAKERTYPE_II,
	SPEAKERTYPE_IIE,
};

#define SPEAKERPHASE_BITNUM			6
#define SPEAKERPHASE_NUM			(1 << SPEAKERPHASE_BITNUM)
#define SPEAKERDELTA_SAMPLENUM		16

#define SPEAKERSTEP_ONES			((SPEAKERDELTA_SAMPLENUM - 1) * \
									SPEAKERPHASE_NUM)
#define SPEAKERSTEP_SAMPLENUM		(SPEAKERDELTA_SAMPLENUM * SPEAKERPHASE_NUM)
#define SPEAKERSTEP_SQUAREWAVEPERIOD	(8 * SPEAKERSTEP_SAMPLENUM)
#define SPEAKERSTEP_HARMONICNUM		(SPEAKERSTEP_SQUAREWAVEPERIOD / \
									(6 * SPEAKERPHASE_NUM))

#define SPEAKER_VOLUME				16384
#define SPEAKERDELTABUFFER_SAMPLENUM	8192

class Speaker : public Device {
public:
	Speaker(class Motherboard * motherboard, UINT32 speakerType);
	
	void onDevicesConnected();
	void onFrameEnd();
	
	void toggleSpeakerOutput();
	void toggleCassetteOutput();
	bool isCassetteInputHigh();
	
private:
	UINT32 speakerType;
	class TimingGenerator * timingGenerator;
	
	SINT32 delta[SPEAKERPHASE_NUM][SPEAKERDELTA_SAMPLENUM];
	SINT32 deltaBuffer[SPEAKERDELTABUFFER_SAMPLENUM];
	SINT32 deltaValue;
	bool isSpeakerHigh;
	
	SINT32 dcFilterX1;
	SINT32 dcFilterY1;
	
	void initDelta();
	void addDelta();
	void integrateDeltaBuffer();
};

#endif
